package cj.web.pay.controllers;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import net.paoding.rose.web.annotation.Param;
import net.paoding.rose.web.annotation.Path;
import net.paoding.rose.web.annotation.rest.Get;
import net.paoding.rose.web.var.Model;

import org.springframework.beans.factory.annotation.Autowired;

import cj.web.pay.alipay.config.AlipayConfig;
import cj.web.pay.alipay.sign.MD5;
import cj.web.pay.alipay.util.AlipayCore;
import cj.web.yc.dao.VideoOrderDAO;

/**
 * 支付宝付款
 * @author Administrator
 *
 */
@Path("alipay")
public class PayController{
	@Autowired
	private VideoOrderDAO videoOrderDAO;
	
	/**
	 * 支付宝
	 * @param id 订单id
	 * @param request
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	@Get("scPay")
	public String scPay(@Param("orderId")int id, @Param("price")String price, 
			HttpServletRequest request) throws UnsupportedEncodingException{
		List<Map> orders = videoOrderDAO.queryById(id);
		
		if(orders != null && orders.size() > 0){
			
			Map order = orders.get(0);
			
			String orderNo = order.get("orderNo").toString();
			String subject = "充值";//商品名称
			subject = URLEncoder.encode(subject, "utf-8");
			
			String showUrl = request.getScheme() +"://" + request.getServerName() + "/";
			showUrl = URLEncoder.encode(showUrl, "utf-8");
			
			String notifyUrl = request.getScheme() +"://" + request.getServerName() + "/SCNotify/ali";
			notifyUrl = URLEncoder.encode(notifyUrl, "utf-8");
			
			String returnUrl = request.getScheme() +"://" + request.getServerName() + "/SCNotify/aliScs";
			returnUrl = URLEncoder.encode(returnUrl, "utf-8");
			
			return "r:payPC?orderNo=" + orderNo
					+ "&subject=" + subject
					+ "&price=" + price
					+ "&showUrl=" + showUrl
					+ "&returnUrl=" + returnUrl
					+ "&notifyUrl=" + notifyUrl;
		}
		
		return "";
	}
	
	/**
	 * 调起支付宝支付页
	 * @param model 
	 * @param orderNo 订单号 必填
	 * @param subject 商品名称 必填
	 * @param price   订单总价，保留两位小数，例如30.00 必填
	 * @param showUrl 商品的链接地址，需URLEncode，可包含如?id=1之类的参数 必填
	 * @param notifyUrl 服务器异步通知页面，不可包含如?id=1之类的参数 
	 * @param body    商品描述 可空
	 * @return
	 * @throws Exception
	 */
	@Get("payPC")
	public String alipayPC(Model model, @Param("orderNo")String orderNo, @Param("subject")String subject, 
			@Param("price")String price, @Param("showUrl")String showUrl, @Param("returnUrl")String returnUrl, @Param("notifyUrl")String notifyUrl, @Param("body")String body) throws Exception{
		if(body == null){
			body = "";
		}
		//把请求参数打包成数组
		Map<String, String> sParaTemp = new HashMap<String, String>();
		sParaTemp.put("service", AlipayConfig.service);
        sParaTemp.put("partner", AlipayConfig.partner);
        sParaTemp.put("seller_id", AlipayConfig.seller_id);
        sParaTemp.put("_input_charset", AlipayConfig.input_charset);
		sParaTemp.put("payment_type", AlipayConfig.payment_type);
		sParaTemp.put("notify_url", notifyUrl);
		sParaTemp.put("return_url", returnUrl);
		sParaTemp.put("out_trade_no", orderNo);
		sParaTemp.put("subject", subject);
		sParaTemp.put("total_fee", price);
		sParaTemp.put("show_url", showUrl);
		//sParaTemp.put("app_pay","Y");//启用此参数可唤起钱包APP支付。
		sParaTemp.put("body", body);
		//其他业务参数根据在线开发文档，添加参数.文档地址:https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.2Z6TSk&treeId=60&articleId=103693&docType=1
        //如sParaTemp.put("参数名","参数值");
		
		Map<String, String> sPara = buildRequestPara(sParaTemp);
		model.add("RequestParams", sPara);
		
		//建立请求
		model.add("ALIPAY_GATEWAY_URL", AlipayConfig.ALIPAY_GATEWAY_NEW + "_input_charset=" + AlipayConfig.input_charset);
		model.add("Method", "get");
		
		return "/views/alipay/alipay.vm";
	}
	
	/**
     * 生成要请求给支付宝的参数数组
     * @param sParaTemp 请求前的参数数组
     * @return 要请求的参数数组
     */
    private static Map<String, String> buildRequestPara(Map<String, String> sParaTemp) {
        //除去数组中的空值和签名参数
        Map<String, String> sPara = AlipayCore.paraFilter(sParaTemp);
        //生成签名结果
        String mysign = buildRequestMysign(sPara);

        //签名结果与签名方式加入请求提交参数组中
        sPara.put("sign", mysign);
        sPara.put("sign_type", AlipayConfig.sign_type);

        return sPara;
    }
    
    /**
     * 生成签名结果
     * @param sPara 要签名的数组
     * @return 签名结果字符串
     */
    private static String buildRequestMysign(Map<String, String> sPara) {
    	String prestr = AlipayCore.createLinkString(sPara); //把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
        String mysign = "";
        if(AlipayConfig.sign_type.equals("MD5")) {
        	mysign = MD5.sign(prestr, AlipayConfig.key, AlipayConfig.input_charset);
        }
        return mysign;
    }
}